package org.design.log.aspect;

import cn.hutool.json.JSONUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.design.log.annotation.ApiLog;
import org.design.log.event.ApiLogEvent;
import org.design.log.util.ApiLogUtils;
import org.design.utils.CommonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

/**
 * ApiLogAspect
 *
 * @author 樊温军
 * @date 2025/6/23 上午8:46
 */
@Slf4j
@Aspect
@Component
public class ApiLogAspect {
    private ApplicationEventPublisher publisher;

    @Autowired
    public void setPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    @SneakyThrows
    @Around("@annotation(apiLog)")
    public Object around(ProceedingJoinPoint point, ApiLog apiLog) {
        String strClassName = point.getTarget().getClass().getName();
        String strMethodName = point.getSignature().getName();
        Object[] args = point.getArgs();
        //2.传参
        StringBuilder params = new StringBuilder();

        for (Object object : args) {
            if (object == null) {
                params.append((Object) null);
            } else {
                try {
                    params.append(JSONUtil.toJsonStr(object));
                } catch (Exception e) {
                    params.append(object);
                }
            }
        }
        log.debug("[类名]:{},[方法]:{},[参数]:{}", strClassName, strMethodName, params);
        org.design.log.entity.ApiLog apiLogParam = ApiLogUtils.getSysLog();
        //描述
        apiLogParam.setTitle(apiLog.value());
        apiLogParam.setParams(params.toString());
        // 发送异步日志事件
        Long startTime = System.currentTimeMillis();
        Object obj = "";
        try {
            obj = point.proceed();
            apiLogParam.setStatus("0");
            apiLogParam.setResult(obj.toString());
        } catch (Exception e) {
            apiLogParam.setStatus("1");
            apiLogParam.setException(CommonUtils.getStackTrace(e));
            throw new RuntimeException(e);
        } finally {
            Long endTime = System.currentTimeMillis();
            apiLogParam.setTime(endTime - startTime);
            // 2025-06-23 开启@ApiLog 注解
            try {
                publisher.publishEvent(new ApiLogEvent(apiLogParam));
            } catch (Exception e) {
                log.error("日志记录异常：", e);
            }
        }
        return obj;
    }

}
